/*
ID: icerupt1
PROG: stall4
LANG: C++11
*/

/* solution
 *
 *
*/
#include <fstream>
#include <iostream>
#include <vector>

std::ifstream fin {"stall4.in" };
std::ofstream fout{"stall4.out"};

int const maxn = 404;
std::vector<std::vector<int>> graph;
int linked[maxn];
bool visited[maxn];
int n, m;

void add_edge(int u, int v) { graph[u].push_back(v); }

typedef std::vector<int>::iterator iter_edge;
bool hungarian_dfs(int u)
{
	for (iter_edge it = graph[u].begin(); it != graph[u].end(); it++) {
		int v = *it;
		if (!visited[v]) {
			visited[v] = true;
			if (linked[v] == -1 || hungarian_dfs(linked[v])) {
				linked[u] = v;
				linked[v] = u;
				return true;
			}
		}
	}
	return false;
}

int main()
{
	std::ios::sync_with_stdio(false);
	fin >> n >> m;
	int node_num = n + m;
	graph.resize(node_num);
	for (int i = 0, t; i < n; i++) {
		fin >> t;
		for (int j = 0, tmp; j < t; j++) {
			fin >> tmp;
			add_edge(i, n + tmp-1);
		}
	}

	int bi_match = 0;
	std::fill(linked, linked + node_num, -1);
	for (int i = 0; i < n; i++) {
		std::fill(visited, visited + node_num, false);
		if (hungarian_dfs(i)) bi_match++;
	}

	std::cout << bi_match << '\n';
	fout << bi_match << '\n';
}
